﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SqlSugar;
using Sunny.UI;
using 数据迁移工具.Common;
using 数据迁移工具.Common.DbContext;
using 数据迁移工具.Factory;

namespace 数据迁移工具
{
    public partial class ModelForm : UIForm
    {
        List<string> dbTypes;
        List<string> tables = new List<string>();
        SugarDbContext sourceDbContext;
        string nameSp = string.Empty;
        string tbPrefixIgnore = string.Empty;
        string targetPath = string.Empty;
        string srcConfigId = string.Empty;

        public string SrcConnStr
        {
            get
            {
                string sql = "";
                DbType type = Enum.Parse<SqlSugar.DbType>(SrcCbBox.SelectedValue.ToString());
                switch (type)
                {
                    case DbType.MySql:
                        sql = $"Server={SrcIPTxt.Text.Trim()};Port={SrcPortTxt.Text.Trim()};Database={SrcDbTxt.Text.Trim()};user={SrcNameTxt.Text.Trim()};Password={SrcPwdTxt.Text.Trim()};AllowLoadLocalInfile=true";
                        break;
                    case DbType.SqlServer:
                        throw new Exception("未实现针对SqlServer的转换");
                        break;
                    case DbType.Sqlite:
                        sql = $"Data Source={SrcIPTxt.Text.Trim()}";
                        break;
                    case DbType.Dm:
                        sql = $"Server={SrcIPTxt.Text.Trim()};Port={SrcPortTxt.Text.Trim()};Database={SrcDbTxt.Text.Trim()};user={SrcNameTxt.Text.Trim()};Password={SrcPwdTxt.Text.Trim()}";
                        break;
                    case DbType.Oracle:
                        sql = $"Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={SrcIPTxt.Text.Trim()})(PORT={SrcPortTxt.Text.Trim()})))(CONNECT_DATA=(SERVICE_NAME=xe)));User Id={SrcNameTxt.Text.Trim()};Password={SrcPwdTxt.Text.Trim()};";
                        break;
                    default:
                        break;
                }

                return sql;
            }
        }


        public ModelForm()
        {
            InitializeComponent();
            Load += ModelForm_Load;
        }

        private void ModelForm_Load(object? sender, EventArgs e)
        {
            dbTypes = this.Tag as List<string>;
            SrcCbBox.DataSource = dbTypes;
        }

        /// <summary>
        /// 连接数据库
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiButton1_Click(object sender, EventArgs e)
        {
            string dbType = SrcCbBox.SelectedValue.ToString();
            string srcIp = SrcIPTxt.Text;
            string srcPort = SrcPortTxt.Text;
            string dbName = SrcDbTxt.Text;
            string username = SrcNameTxt.Text;
            string password = SrcPwdTxt.Text;

            bool flag = Form1.CheckParam(Origin.Source, dbType, srcIp, srcPort, dbName, username, password);
            if (!flag) return;

            srcConfigId = dbType + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            ConnectionConfig srcConnConfig = Form1.BuildConfig(Origin.Source, dbType, srcConfigId, SrcConnStr, null);
            sourceDbContext = DbFactory.CreateDbContext(Enum.Parse<DbType>(dbType), srcConnConfig);
            bool connState = sourceDbContext.DB.Ado.IsValidConnection();
            if (connState)
            {
                ConnStateLb.ForeColor = Color.LimeGreen;
                ConnStateLb.Text = "已连接";
                TbInfoBtn.Enabled = true;
                AllSelectBtn.Checked = false;
                AllCancelBtn.Enabled = false;
            }
            else
            {
                ConnStateLb.ForeColor = Color.Red;
                ConnStateLb.Text = "未连接";
                TbInfoBtn.Enabled = false;

            }
        }

        string initDirPath = Directory.GetCurrentDirectory();
        /// <summary>
        /// 选择实体类生成路径
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiButton2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fileDialog = new FolderBrowserDialog();
            fileDialog.InitialDirectory = initDirPath;
            DialogResult result = fileDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                initDirPath = fileDialog.SelectedPath;
                DirPathTxt.Text = initDirPath;
                targetPath = initDirPath;
            }
        }

        private void NameSpCk_CheckedChanged(object sender, EventArgs e)
        {
            if (NameSpCk.Checked)
            {
                NameSpTxt.Visible = true;
            }
            else
            {
                NameSpTxt.Visible = false;
            }
        }

        private void TbNameCk_CheckedChanged(object sender, EventArgs e)
        {
            if (TbNameCk.Checked)
            {
                TbNameTxt.Visible = true;
            }
            else
            {
                TbNameTxt.Visible = false;
            }
        }

        /// <summary>
        /// 命名空间设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void NameSpTxt_TextChanged(object sender, EventArgs e)
        {
            nameSp = (sender as UITextBox).Text;
        }

        /// <summary>
        /// 表名前缀忽略设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TbNameTxt_TextChanged(object sender, EventArgs e)
        {
            tbPrefixIgnore = (sender as UITextBox).Text;
        }

        private void AllSelectBtn_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < CkTbListBox.Items.Count; i++)
            {
                CkTbListBox.SetItemChecked(i, true);
            }
            tables = CkTbListBox.Items.Cast<string>().ToList();
            AllCancelBtn.Checked = false;
        }

        private void AllCancelBtn_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < CkTbListBox.Items.Count; i++)
            {
                CkTbListBox.SetItemChecked(i, false);
            }
            tables.Clear();
            AllSelectBtn.Checked = false;
        }

        /// <summary>
        /// 获取当前数据库连接下的表信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiButton4_Click(object sender, EventArgs e)
        {
            if (sourceDbContext == null)
            {
                MessageBox.Show("数据源未初始化");
                return;
            }

            string dbName = SrcDbTxt.Text;
            List<TableInfo> tableInfos = sourceDbContext.GetTableInfos(dbName);
            CkTbListBox.Items.Clear();
            CkTbListBox.Items.AddRange(tableInfos.Select(t => t.TbName).ToArray());
        }

        /// <summary>
        /// 开始生成实体类
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void uiButton3_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(targetPath))
            {
                MessageBox.Show("生成路径未选择");
                return;
            }

            try
            {
                ProcessLogForm form = new ProcessLogForm();
                form.Show();
                await Task.Run(() =>
                {
                    if (!string.IsNullOrEmpty(tbPrefixIgnore) && !string.IsNullOrEmpty(nameSp))
                    {
                        sourceDbContext.GenerateModels(srcConfigId, targetPath, tables, tbPrefixIgnore, nameSp, form.UpdateProgressBar, form.UpdateLogListBox);
                    }
                    else if (!string.IsNullOrEmpty(tbPrefixIgnore))
                    {
                        sourceDbContext.GenerateModels(srcConfigId, targetPath, tables, ignorePrefix: tbPrefixIgnore, processMonitor: form.UpdateProgressBar, processLog: form.UpdateLogListBox);
                    }
                    else if (!string.IsNullOrEmpty(nameSp))
                    {
                        sourceDbContext.GenerateModels(srcConfigId, targetPath, tables, namesp: nameSp, processMonitor: form.UpdateProgressBar, processLog: form.UpdateLogListBox);
                    }
                    else
                    {
                        sourceDbContext.GenerateModels(srcConfigId, targetPath, tables, processMonitor: form.UpdateProgressBar, processLog: form.UpdateLogListBox);
                    }
                });
                MessageBox.Show("实体类生成成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"实体类生成失败: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void CkTbListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            tables.Clear();
            tables.AddRange(CkTbListBox.CheckedItems.Cast<string>().ToList());
        }

        private void SrcCbBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            SrcIPTxt.ResetText();
            SrcPortTxt.ResetText();
            SrcDbTxt.ResetText();
            SrcNameTxt.ResetText();
            SrcPwdTxt.ResetText();

            sourceDbContext = null;
            TbInfoBtn.Enabled = false;
            CkTbListBox.Items.Clear();
        }

        private void DirPathTxt_TextChanged(object sender, EventArgs e)
        {
            targetPath = DirPathTxt.Text.Trim();
        }
    }
}
